package com.cskaoyan.javase.object._6clone.exercise;

/**
 * 深度克隆练习：请完成类FirstLevel的深度克隆。
 *
 * 现在有三个类 FirstLevel 、SecondLevel 、ThirdLevel
 *
 * FirstLevel 类有三个属性：
 *
 * int firstIntValue;
 * double firstDoubleValue;
 * SecondLevel second;
 *
 * SecondLevel 类有三个属性：
 *
 * int secondIntValue;
 * double secondDoubleValue;
 * ThirdLevel third;
 *
 * ThirdLevel 类有两个属性：
 *
 * int thirdIntValue;
 * double thirdDoubleValue;
 *
 * @since 21:11
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) throws CloneNotSupportedException {
        First first = new First(10, 20, new Second(100, 200, new Third(1000, 2000)));
        First cloneFirst = first.clone();

    }
}

class First implements Cloneable {
    int firstIntValue;
    double firstDoubleValue;
    Second second;

    public First(int firstIntValue, double firstDoubleValue, Second second) {
        this.firstIntValue = firstIntValue;
        this.firstDoubleValue = firstDoubleValue;
        this.second = second;
    }

    @Override
    protected First clone() throws CloneNotSupportedException {
        // 1.深克隆是在浅克隆的基础上来完成.
        First cloneFirst = (First) super.clone();
        // 2.将对象中引用所指向的对象克隆一份
        Second cloneSecond = second.clone();
        // 3.将克隆对象中的克隆引用指向新的克隆对象
        cloneFirst.second = cloneSecond;
        return cloneFirst;
    }
}

class Second implements Cloneable {
    int secondIntValue;
    double secondDoubleValue;
    Third third;

    public Second(int secondIntValue, double secondDoubleValue, Third third) {
        this.secondIntValue = secondIntValue;
        this.secondDoubleValue = secondDoubleValue;
        this.third = third;
    }

    @Override
    protected Second clone() throws CloneNotSupportedException {
        Second cloneSecond = (Second) super.clone();
        Third cloneThird = third.clone();
        cloneSecond.third = cloneThird;
        return cloneSecond;
    }
}

class Third implements Cloneable{
    int thirdIntValue;
    double thirdDoubleValue;

    // 类中String引用数据类型成员变量,是不需要做克隆操作的
    String name;

    public Third(int thirdIntValue, double thirdDoubleValue) {
        this.thirdIntValue = thirdIntValue;
        this.thirdDoubleValue = thirdDoubleValue;
    }

    @Override
    protected Third clone() throws CloneNotSupportedException {
        return (Third) super.clone();
    }
}